package com.vcredit.creditcat.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.vcredit.bird.enumtype.MobileStatusEnum;
import com.vcredit.creditcat.dto.creditrepository.AuthItemDto;
import com.vcredit.creditcat.dto.creditrepository.AuthItemFilterDto;
import com.vcredit.creditcat.dto.creditrepository.AuthItemFilterParamDto;
import com.vcredit.creditcat.dto.creditrepository.CreditLibraryDto;
import com.vcredit.creditcat.dto.creditrepository.CustCreditRepositoryDto;
import com.vcredit.creditcat.dto.creditrepository.ItemReportStatusDto;
import com.vcredit.creditcat.dto.creditrepository.ItemStatusDto;
import com.vcredit.creditcat.dto.product.MerchantProductDto;
import com.vcredit.creditcat.enumtype.AssureStatusEnum;
import com.vcredit.creditcat.enumtype.AuthAccumulationStatusEnum;
import com.vcredit.creditcat.enumtype.AuthCreditStatusEnum;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.enumtype.CreditStatusEnum;
import com.vcredit.creditcat.enumtype.EMStatusEnum;
import com.vcredit.creditcat.enumtype.SpeedloanAuthFailReasonEnum;
import com.vcredit.creditcat.model.Ability;
import com.vcredit.creditcat.model.AuthAccumulation;
import com.vcredit.creditcat.model.AuthAlipay;
import com.vcredit.creditcat.model.AuthCreditcard;
import com.vcredit.creditcat.model.AuthIdentity;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthJd;
import com.vcredit.creditcat.model.AuthMobile;
import com.vcredit.creditcat.model.AuthNetcredit;
import com.vcredit.creditcat.model.AuthProccess;
import com.vcredit.creditcat.model.AuthSecredit;
import com.vcredit.creditcat.model.AuthSocial;
import com.vcredit.creditcat.model.AuthTaobao;
import com.vcredit.creditcat.model.CreditAssure;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.model.CustSupplementItem;
import com.vcredit.creditcat.model.ItemCategory;
import com.vcredit.creditcat.model.MerchantProduct;
import com.vcredit.creditcat.model.ProductItem;
import com.vcredit.creditcat.model.ProductSupplementItem;
import com.vcredit.creditcat.model.base.AbstractItem;
import com.vcredit.creditcat.service.speedloan.SpeedloanService;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.EnumExtUtil;
import com.vcredit.creditcat.util.Utility;
import com.vcredit.creditcat.vo.auth.supplement.CustSupplementItemExt;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.BeanUtil;

@Service
public class CustCreditRepositoryService {
	@Autowired
	private AuthItemService authItemService;
	@Autowired
	private AuthProccessService authProccessService;
	@Autowired
	private ItemCategoryService itemCategoryService;
	@Autowired
	private AbilityService abilityService;
	@Autowired
	private ProductItemService productItemService;
	@Autowired
	private AuthAlipayService authAlipayService;
	@Autowired
	private AuthJdService authJdService;
	@Autowired
	private AuthTaobaoService authTaobaoService;
	@Autowired
	private AuthSecreditService authSecreditService;
	@Autowired
	private AuthMobileService authMobileService;
	@Autowired
	private AuthAccumulationService authAccumulationService;
	@Autowired
	private AuthSocialService authSocialService;
	@Autowired
	private AuthNetcreditService authNetcreditService;
	@Autowired
	private AuthCreditcardService authCreditcardService;
	@Autowired
	private CreditAssureService creditAssureService;
	@Autowired
	private AuthIdentityService authIdentityService;
	@Autowired
	private MerchantProductService merchantProductService;
	@Autowired
	private CustProductApplyService custProductApplyService;
	@Autowired
	private SpeedloanService speedloanService;
	@Autowired
	private CustService custService;
	@Autowired
	private CustSupplementItemService custSupplementItemService;
	@Autowired
	private ProductSupplementItemService productSupplementItemService;

	@Log
	public CustCreditRepositoryDto getCustCreditRepository(Long processId) {
		Map<Integer, ItemCategory> itemCategoryMaps = itemCategoryService.findAll();// 认证项大类

		Map<Long, AuthItem> itemsMaps = authItemService.findAll();// 认证项主档

		AuthProccess authProccess = authProccessService.findByProcessId(processId);// 用户完成项

		Map<Integer, List<AuthItemDto>> totalMap = new HashMap<Integer, List<AuthItemDto>>();

		CustCreditRepositoryDto custCreditRepositoryDto = new CustCreditRepositoryDto();
		List<CreditLibraryDto> CreditLibraryList = new ArrayList<CreditLibraryDto>();

		Integer successCode = authProccess.getSuccessCode();
		int doneQty = 0;
		int itemAll = 0;
		for (ItemCategory itemCategory : itemCategoryMaps.values()) {
			List<AuthItemDto> authItemList = new ArrayList<AuthItemDto>();
			CreditLibraryDto creditLibraryDto = new CreditLibraryDto();
			creditLibraryDto.setType(itemCategory.getCateName());
			creditLibraryDto.setItems(authItemList);
			CreditLibraryList.add(creditLibraryDto);
			totalMap.put(itemCategory.getCateId(), authItemList);
		}

		Iterator<Entry<Long, AuthItem>> it = itemsMaps.entrySet().iterator();
		while (it.hasNext()) {
			AuthItem item = it.next().getValue();
			if (!item.getIsRepository()) { // 排除不在信用库中显示的认证项
				it.remove();
				continue;
			}
			AuthItemDto authItemDto = new AuthItemDto();
			authItemDto.setName(item.getItemName());
			authItemDto.setFrontId(item.getAuthCode().toString());
			authItemDto.setIconUrl(item.getItemIcon());
			authItemDto.setDesc(item.getItemDesc());
			authItemDto.setIsFinish(0);
			authItemDto.setItemSort(item.getItemSort());
			if ((successCode & item.getAuthCode()) == item.getAuthCode()) {
				doneQty++;
				authItemDto.setIsFinish(1);
			}
			List<AuthItemDto> obj = totalMap.get(item.getCateId());
			if (obj != null)
				obj.add(authItemDto);

		}
		itemAll = itemsMaps.size();
		custCreditRepositoryDto.setDoneQty(--doneQty);
		custCreditRepositoryDto.setTotalQty(--itemAll);
		custCreditRepositoryDto.setCreditLibrary(CreditLibraryList);
		return custCreditRepositoryDto;
	}

	@Log
	public AuthItemFilterDto getAuthItems(AuthItemFilterParamDto param, Long processId) {
		String filterId = param.getFilterId();
		String[] filterIds = new String[1];
		if (StringUtils.isNotEmpty(filterId)) {
			if (param.getFilterId().endsWith(",")) {
				filterId = filterId.substring(0, filterId.length() - 1);
			}
			filterIds[0] = filterId;
			if (param.getFilterId().indexOf(",") != -1) {
				filterIds = filterId.split(",");
			}
		}
		int filterPattern = Integer.valueOf(param.getFilterPattern());
		int filter = Integer.valueOf(param.getFilterStatus());
		Integer successCode = 0; // 已完成项
		Integer targetCode = 0; // 目标项
		AuthProccess authProccess = authProccessService.findByProcessId(processId);// 用户完成项
		successCode = authProccess.getSuccessCode();
		List<AuthItemDto> authItemDtoList = new ArrayList<AuthItemDto>(); // 装载AuthItem集合
		AuthItemFilterDto result = new AuthItemFilterDto();
		for (String obj : filterIds) {
			switch (filterPattern) {
			case 1: // 特权任务
				Ability ability = abilityService.findById(Long.valueOf(obj));
				targetCode = ability.getMinCodeIndeed();
				break;
			case 2:
				ProductItem productItem = productItemService.findByProductId(Long.valueOf(obj));
				targetCode = productItem.getMinCode();
				break;
			case 4:
				List<AuthItem> authItems = authItemService.findUndoAuthItems(authProccess.getSuccessCode());
				Collections.sort(authItems, new Comparator<AuthItem>() {
					@Override
					public int compare(AuthItem item1, AuthItem item2) {
						if (item1.getItemPriority() > item2.getItemPriority())
							return 1;
						else
							return -1;
					}
				});
				for (int i = 0, size = authItems.size(); i < size; i++) {
					if (3 == i) {
						break;
					}
					AuthItem authItem = authItems.get(i);
					authItemDtoList
							.add(new AuthItemDto(authItem.getItemName(), authItem.getItemDesc(), authItem.getItemIcon(), 0, authItem.getAuthCode().toString(), authItem.getItemBasescore() / 100, authItem.getItemSort()));
				}
				result.setQueryResult(authItemDtoList);
				return result;
			default:
				break;
			}
			if (filter == 1) { // 未完成项
				targetCode = targetCode - (successCode & targetCode);
			} else if (filter == 2) { // 完成项
				targetCode = (successCode & targetCode);
			}
			List<AuthItem> AuthItemList = authItemService.getItemByCodes(targetCode);
			for (AuthItem item : AuthItemList) {
				// 排除实名认证
				if (AuthItemEnum.REAL_NAME.getCode() == item.getAuthCode()) {
					continue;
				}
				AuthItemDto authItemDto = new AuthItemDto();
				authItemDto.setName(item.getItemName());
				authItemDto.setFrontId(item.getAuthCode().toString());
				authItemDto.setIconUrl(item.getItemIcon());
				authItemDto.setDesc(item.getItemDesc());
				authItemDto.setIsFinish(0);
				authItemDto.setPromotionScore(item.getItemBasescore() / 100);
				authItemDto.setItemSort(item.getItemSort());
				if (filter == 0) {
					if ((successCode & item.getAuthCode()) == item.getAuthCode()) {
						authItemDto.setIsFinish(1);
					}
				} else if (filter == 1) {
					authItemDto.setIsFinish(0);
				} else if (filter == 2) {
					authItemDto.setIsFinish(1);
				}
				authItemDtoList.add(authItemDto);
			}
		}
		result.setQueryResult(authItemDtoList);
		return result;
	}

	@Log
	@Transactional(propagation = Propagation.REQUIRED)
	public ItemStatusDto getStatus(String authItemCode, Integer flag, Cust cust) throws Exception {
		Integer authItemCodeIntVal = Integer.valueOf(authItemCode);

		if (!(authItemCodeIntVal % 2 == 0)) { // 认证code为奇数则为补充认证项
			return this.getSupplementItemStatus(authItemCodeIntVal, flag, cust);
		}

		AuthItemEnum param = EnumExtUtil.getEnumOnValue(AuthItemEnum.class, String.valueOf(authItemCodeIntVal), "code");
		Long proccessId = cust.getLastProccessId();
		AuthItem authItem = authItemService.getItemByCode(authItemCodeIntVal);
		AuthProccess authProccess = authProccessService.findByProcessId(proccessId);// 用户完成项
		if (null == authProccess) {
			authProccess = new AuthProccess();
			authProccess.setSuccessCode(0);
		}
		ItemStatusDto itemStatusDto = new ItemStatusDto();
		itemStatusDto.setItemDesc(authItem.getItemDesc());
		itemStatusDto.setItemName(authItem.getItemName());
		itemStatusDto.setItemIcon(authItem.getItemIcon());
		itemStatusDto.setItemCode(authItem.getAuthCode());
		itemStatusDto.setItemId(authItem.getItemId());

		if (null == proccessId) { // 未登录情况，返回未完成状态
			itemStatusDto.setStatus("0");
			return itemStatusDto;
		}

		switch (param) {
		case ALIPAY: // 支付宝
			AuthAlipay authAlipay = authAlipayService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authAlipay && null != flag && flag == 1) {
				authAlipay.setAuthStatus(EMStatusEnum.INIT.getCode());
				authAlipayService.resetStatus(authAlipay);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authAlipay);
			break;
		case FUND_CREDIT: // 公积金
			AuthAccumulation authAccumulation = authAccumulationService.findByProccessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authAccumulation && null != flag && flag == 1) {
				authAccumulation.setAuthStatus(AuthAccumulationStatusEnum.INIT.getCode());
				authAccumulationService.update(authAccumulation);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto.setFailStatus("0");
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authAccumulation);
			itemStatusDto.setName(cust.getCustName());
			itemStatusDto.setIdCard(cust.getCustIdno());
			break;
		case JINGDONG: // 京东
			AuthJd authJd = authJdService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authJd && null != flag && flag == 1) {
				authJd.setAuthStatus(EMStatusEnum.INIT.getCode());
				authJdService.resetStatus(authJd);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto.setFailStatus("0");
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authJd);
			break;
		case MOBILE: // 手机
			AuthMobile authMobile = authMobileService.findByProcessIdAndType(proccessId, 0);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authMobile && null != flag && flag == 1) {
				authMobile.setResultStatus(MobileStatusEnum.UN_AUTHENTICATE.getCode());
				authMobileService.resetStatus(authMobile);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authMobile);
			break;
		case SESAME_CREDIT: // 芝麻信用
			AuthSecredit authSecredit = authSecreditService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authSecredit && null != flag && flag == 1) {
				authSecredit.setAuthStatus(EMStatusEnum.INIT.getCode());
				authSecreditService.resetStatus(authSecredit);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authSecredit);
			break;
		case SOCIAL_CREDIT: // 社保
			AuthSocial authSocial = authSocialService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authSocial && null != flag && flag == 1) {
				authSocial.setAuthStatus(AuthAccumulationStatusEnum.INIT.getCode());
				authSocialService.resetStatus(authSocial);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto.setFailStatus("0");
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authSocial);
			break;
		case TAOBAO: // 淘宝
			AuthTaobao authTaobao = authTaobaoService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authTaobao && null != flag && flag == 1) {
				authTaobao.setAuthStatus(EMStatusEnum.INIT.getCode());
				authTaobaoService.resetStatus(authTaobao);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto.setFailStatus("0");
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authTaobao);
			break;
		case BANK_CREDIT: // 央行征信
			AuthNetcredit netcredit = authNetcreditService.findByProcessId(proccessId);
			if (null != netcredit && null != flag && flag == 1) {
				netcredit.setCreditStatus(AuthCreditStatusEnum.INIT.getCode());
				authNetcreditService.update(netcredit);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
				itemStatusDto.setStatus("0");
				break;
			}
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authProccess.getSuccessCode());
			break;
		case CREDIT_CARD: // 信用卡
			AuthCreditcard creditcard = authCreditcardService.findByProcessId(proccessId);
			if (null != creditcard && null != flag && flag == 1) {
				creditcard.setAuthStatus(CreditStatusEnum.INIT.getCode());
				authCreditcardService.update(creditcard);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
				itemStatusDto.setStatus("0");
				break;
			}
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authProccess.getSuccessCode());
			break;
		case FOREIGN_CREDIT: // 机构版征信
			CreditAssure creditAssure = creditAssureService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != creditAssure && null != flag && flag == 1) {
				creditAssure.setAssureStatus(AssureStatusEnum.Invalid.getCode());
				creditAssureService.resetStatus(creditAssure);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, creditAssure);
			break;
		case IDENTITY_REAL: // 身份证认证（高级实名）
			AuthIdentity authIdentity = authIdentityService.findByProcessId(proccessId);
			if (null != authIdentity
					// 身份证正反面
					&& StringUtils.isNotBlank(authIdentity.getIdFront()) && StringUtils.isNotBlank(authIdentity.getIdBack())
					// 手持照
					&& StringUtils.isNotBlank(authIdentity.getIdHandheld())
					// 签名
					&& StringUtils.isNotBlank(cust.getSignatureImage())) {
				itemStatusDto.setStatus("1");
			} else {
				itemStatusDto.setStatus("0");
			}
			break;
		case VERIFY_FACE_PAIR: // 身份证认证（高级实名）
			AuthIdentity identity = authIdentityService.findByProcessId(proccessId);
			if (null != identity
					// 身份证正反面
					&& StringUtils.isNotBlank(identity.getIdFront()) && StringUtils.isNotBlank(identity.getIdBack())
					// 人脸照
					&& StringUtils.isNotBlank(identity.getIdFace())
					// 签名
					&& StringUtils.isNotBlank(cust.getSignatureImage())) {
				itemStatusDto.setStatus("1");
			} else {
				itemStatusDto.setStatus("0");
			}
			break;
		default: // 其他无过期时间
			itemStatusDto = checkItemStatus(param.getCode(), itemStatusDto, authProccess.getSuccessCode());
			break;
		}
		this.setFailReason(itemStatusDto, param.getCode());
		return itemStatusDto;
	}

	/**
	 * 获取补充认证项状态
	 * 
	 * @author zhaoqi01
	 * @param authItemCodeIntVal
	 * @param flag
	 * @param cust
	 * @return
	 */
	private ItemStatusDto getSupplementItemStatus(Integer authItemCodeIntVal, Integer flag, Cust cust) {
		ItemStatusDto result = new ItemStatusDto();
		CustSupplementItemExt itemExt = custSupplementItemService.findExtByCustAndItemCode(cust, authItemCodeIntVal);
		CustSupplementItem custSupplementItem = itemExt.getCustSupplementItem();
		ProductSupplementItem productSupplementItem = itemExt.getProductSupplementItem();

		result.setItemId(productSupplementItem.getItemId());
		result.setItemCode(authItemCodeIntVal);
		result.setItemName(productSupplementItem.getItemName());
		result.setItemIcon(productSupplementItem.getItemIcon());
		result.setItemDesc(productSupplementItem.getItemDesc());
		result.setStatus(custSupplementItem.getStatus() + "");

		if (null != flag && 1 == flag) { // 重置补充认证项
			if (custSupplementItem.getId() != null) {
				custSupplementItem.setStatus(0);
				custSupplementItemService.update(custSupplementItem);
			}
			result.setStatus("0");
		}

		return result;
	}

	private ItemStatusDto checkItemStatus(Integer authItemCode, ItemStatusDto itemStatusDto, AbstractItem item) {
		if (item == null) {
			itemStatusDto.setStatus("0");
			return itemStatusDto;
		}
		if (authItemCode.equals(AuthItemEnum.MOBILE.getCode())) { // 手机
			AuthMobile mobileItem = (AuthMobile) item;
			if (item.getStatus() == MobileStatusEnum.NOT_REAL_NAME.getCode()) { // 实名未认证
				itemStatusDto.setStatus("3");
				itemStatusDto.setFailStatus("1");
				itemStatusDto.setName(mobileItem.getRegisterName());
				itemStatusDto.setIdCard(mobileItem.getRegisterIdNo());
				return itemStatusDto;
			} else if (item.getStatus() == MobileStatusEnum.AUTHENTICATING.getCode()) { // 认证中
				itemStatusDto.setStatus("2");
				return itemStatusDto;
			} else if (item.getStatus() == MobileStatusEnum.REAL_NAME.getCode()) { // 认证完成
				itemStatusDto.setStatus("1");
				return itemStatusDto;
			} else if (item.getStatus() == MobileStatusEnum.UN_AUTHENTICATE.getCode()) { // 未认证
				itemStatusDto.setStatus("0");
				return itemStatusDto;
			} else {
				itemStatusDto.setFailStatus("0");
				itemStatusDto.setStatus("3");
				return itemStatusDto;
			}
		} else if (authItemCode.equals(AuthItemEnum.SOCIAL_CREDIT.getCode()) || authItemCode.equals(AuthItemEnum.FUND_CREDIT.getCode())) { // 社保与公积金
			switch (item.getStatus()) {
			case 2:// 登录成功
				itemStatusDto.setStatus("2");
				break;
			case 3:// 认证成功
				itemStatusDto.setStatus("1");
				break;
			case 4:// 认证失败
				itemStatusDto.setStatus("3");
				itemStatusDto.setFailStatus("1");
				break;
			default:
				itemStatusDto.setStatus("0");
				break;
			}
			return itemStatusDto;
		} else if (authItemCode.equals(AuthItemEnum.JINGDONG.getCode()) || authItemCode.equals(AuthItemEnum.TAOBAO.getCode())) {
			switch (item.getStatus()) {
			case 2:// 登录成功
				itemStatusDto.setStatus("2");
				break;
			case 3:// 认证失败
				itemStatusDto.setStatus("3");
				itemStatusDto.setFailStatus("1");
				break;
			case 4:// 认证成功
				itemStatusDto.setStatus("1");
				break;
			default:
				itemStatusDto.setStatus("0");
				break;
			}
			return itemStatusDto;
		} else if (authItemCode.equals(AuthItemEnum.FOREIGN_CREDIT.getCode())) { // 机构版征信
			if (item.getStatus() == AssureStatusEnum.Fail.getCode() || item.getStatus() == AssureStatusEnum.PreAuditFail.getCode()) {
				itemStatusDto.setStatus("3");
			} else if (item.getStatus() == AssureStatusEnum.Report.getCode()) {
				itemStatusDto.setStatus("1");
			} else if (item.getStatus() == AssureStatusEnum.Invalid.getCode()) {
				itemStatusDto.setStatus("0");
			} else {
				itemStatusDto.setStatus("2");
			}
			return itemStatusDto;
		} else {
			switch (item.getStatus()) {
			case 2:
				itemStatusDto.setStatus("2");
				break;
			case 3:
				itemStatusDto.setStatus("3");
				break;
			case 4:
				itemStatusDto.setStatus("1");
				break;
			default:
				itemStatusDto.setStatus("0");
				break;
			}
		}
		return itemStatusDto;
	}

	/**
	 * 设置认证项失败原因
	 * 
	 * @author zhaoqi01
	 * @param itemStatusDto
	 * @param itemCode
	 */
	private void setFailReason(ItemStatusDto itemStatusDto, int itemCode) {
		if (!"3".equals(itemStatusDto.getStatus())) {
			return;
		}
		if (itemCode == AuthItemEnum.MOBILE.getCode()) { // 手机
			if ("1".equals(itemStatusDto.getFailStatus()))
				itemStatusDto.setFailReason(SpeedloanAuthFailReasonEnum.mobile_no_realname.getReason());
			else
				itemStatusDto.setFailReason(SpeedloanAuthFailReasonEnum.mobile_getinfo_fail.getReason());
		} else {
			for (SpeedloanAuthFailReasonEnum speedloanAuthFailReasonEnum : SpeedloanAuthFailReasonEnum.values()) {
				if (speedloanAuthFailReasonEnum.getItemCode().intValue() == itemCode) {
					itemStatusDto.setFailReason(speedloanAuthFailReasonEnum.getReason());
					break;
				}
			}
		}
		if (StringUtils.isBlank(itemStatusDto.getFailReason())) {
			itemStatusDto.setFailReason(SpeedloanAuthFailReasonEnum.orther_fail.getReason());
		}
	}

	private ItemStatusDto checkItemStatus(Integer authItemCode, ItemStatusDto itemStatusDto, Integer finishCode) {
		if ((finishCode & authItemCode) == authItemCode.intValue()) {
			itemStatusDto.setStatus("1");
		} else {
			itemStatusDto.setStatus("0");
		}
		return itemStatusDto;
	}

	private ItemReportStatusDto checkReportStatus(Integer authItemCode, ItemReportStatusDto itemStatusDto, Integer finishCode) {
		if ((finishCode & authItemCode) == authItemCode.intValue()) {
			itemStatusDto.setStatus("1");
		} else {
			itemStatusDto.setStatus("0");
		}
		return itemStatusDto;
	}

	/**
	 * 扣除用户对该认证项的完成分
	 * 
	 * @author zhaoqi01
	 * @param authItemCode
	 */
	private void deductSucCodeByAuthItemId(AuthProccess authProccess, Integer authItemCode) {
		if ((authProccess.getSuccessCode().intValue() & authItemCode.intValue()) == authItemCode.intValue()) {
			authProccess.setSuccessCode(authProccess.getSuccessCode().intValue() ^ authItemCode.intValue());
			authProccessService.update(authProccess);
		}
	}

	/**
	 * 查询可以申请的产品
	 * 
	 * @author zhaoqi01
	 * @param custId
	 * @return
	 * @throws ParseException
	 */
	@Log
	public List<MerchantProductDto> queryCanApplyProducts(Long custId) throws ParseException {
		List<MerchantProductDto> list = new ArrayList<MerchantProductDto>();
		List<MerchantProduct> products = merchantProductService.findAuthByProcessIdAndTechnical(custService.findById(custId).getLastProccessId(), true);
		if (Utility.isNullOrEmpty(products)) {
			return list;
		}
		List<CustProductApply> custProductApplyList = custProductApplyService.findByCustId(custId);
		if (Utility.isNullOrEmpty(custProductApplyList)) {
			this.copyProductsToDtos(products, list);
			return list;
		}

		Iterator<MerchantProduct> it = products.iterator();
		while (it.hasNext()) {
			MerchantProduct product = it.next();
			for (CustProductApply productApply : custProductApplyList) {
				if (productApply.getProductId() - product.getProductId() == 0 && !custProductApplyService.canProductApplyAgin(productApply)) {
					it.remove();
					break;
				}
			}
		}
		this.copyProductsToDtos(products, list);
		return list;
	}

	private void copyProductsToDtos(List<MerchantProduct> products, List<MerchantProductDto> dtos) {
		for (MerchantProduct merchantProduct : products) {
			MerchantProductDto merchantProductDto = new MerchantProductDto();
			BeanUtil.copy(merchantProduct, merchantProductDto);
			dtos.add(merchantProductDto);
		}
	}

	private ItemReportStatusDto checkStatus(Integer authItemCode, ItemReportStatusDto itemStatusDto, AbstractItem item) throws ParseException {
		if (item == null) {
			itemStatusDto.setStatus("0");
			return itemStatusDto;
		}
		if (authItemCode.equals(AuthItemEnum.MOBILE.getCode())) { // 手机
			if (item.getStatus() == MobileStatusEnum.NOT_REAL_NAME.getCode()) { // 实名未认证
				itemStatusDto.setStatus("3");
				return itemStatusDto;
			} else if (item.getStatus() == MobileStatusEnum.AUTHENTICATING.getCode()) { // 认证中
				itemStatusDto.setStatus("2");
				return itemStatusDto;
			} else if (item.getStatus() == MobileStatusEnum.REAL_NAME.getCode()) { // 认证完成
				itemStatusDto.setStatus("1");
				SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				Date datetime = df.parse(item.getExpiredTime());
				String times = df.format(datetime);
				int buttonDay = ConcurrentDateUtil.daysBetween(ConcurrentDateUtil.formatDateTime(new Date()), times);
				if (buttonDay < 0) {
					itemStatusDto.setStatus("4");
					itemStatusDto.setExecpiseTime(times);
					itemStatusDto.setExpiredDays(Math.abs(buttonDay));
				}
				return itemStatusDto;
			} else if (item.getStatus() == MobileStatusEnum.UN_AUTHENTICATE.getCode()) { // 未认证
				itemStatusDto.setStatus("0");
				return itemStatusDto;
			} else {
				itemStatusDto.setStatus("3");
				return itemStatusDto;
			}
		} else if (authItemCode.equals(AuthItemEnum.SOCIAL_CREDIT.getCode()) || authItemCode.equals(AuthItemEnum.FUND_CREDIT.getCode())) { // 社保与公积金
			switch (item.getStatus()) {
			case 2:// 登录成功
				itemStatusDto.setStatus("2");
				break;
			case 3:// 认证成功
				itemStatusDto.setStatus("1");
				break;
			case 4:// 认证失败
				itemStatusDto.setStatus("3");
				break;
			default:
				itemStatusDto.setStatus("0");
				break;
			}
			return itemStatusDto;
		} else if (authItemCode.equals(AuthItemEnum.JINGDONG.getCode()) || authItemCode.equals(AuthItemEnum.TAOBAO.getCode())) {
			switch (item.getStatus()) {
			case 2:// 登录成功
				itemStatusDto.setStatus("2");
				break;
			case 3:// 认证失败
				itemStatusDto.setStatus("3");
				break;
			case 4:// 认证成功
				itemStatusDto.setStatus("1");
				break;
			default:
				itemStatusDto.setStatus("0");
				break;
			}
			return itemStatusDto;
		} else if (authItemCode.equals(AuthItemEnum.FOREIGN_CREDIT.getCode())) { // 机构版征信
			if (item.getStatus() == AssureStatusEnum.Fail.getCode() || item.getStatus() == AssureStatusEnum.PreAuditFail.getCode()) {
				itemStatusDto.setStatus("3");
			} else if (item.getStatus() == AssureStatusEnum.Report.getCode()) {
				itemStatusDto.setStatus("1");
			} else if (item.getStatus() == AssureStatusEnum.Invalid.getCode()) {
				itemStatusDto.setStatus("0");
			} else {
				itemStatusDto.setStatus("2");
			}
			return itemStatusDto;
		} else {
			switch (item.getStatus()) {
			case 2:
				itemStatusDto.setStatus("2");
				break;
			case 3:
				itemStatusDto.setStatus("3");
				break;
			case 4:
				itemStatusDto.setStatus("1");
				break;
			default:
				itemStatusDto.setStatus("0");
				break;
			}
		}
		return itemStatusDto;
	}

	/**
	 * chengxin
	 * 
	 * @param authItemCode
	 * @param flag
	 * @param cust
	 * @return
	 * @throws Exception
	 */
	@Log
	@Transactional(propagation = Propagation.REQUIRED)
	public ItemReportStatusDto getAuthStatus(String authItemCode, Integer flag, Cust cust) throws Exception {
		ItemReportStatusDto reportStatus = new ItemReportStatusDto();
		Integer authItemCodeIntVal = Integer.valueOf(authItemCode);

		/*
		 * if(!(authItemCodeIntVal % 2 == 0)) { // 认证code为奇数则为补充认证项 return
		 * this.getSupplementItemStatus(authItemCodeIntVal, flag, cust); }
		 */

		AuthItemEnum param = EnumExtUtil.getEnumOnValue(AuthItemEnum.class, String.valueOf(authItemCodeIntVal), "code");
		Long proccessId = cust.getLastProccessId();
		AuthItem authItem = authItemService.getItemByCode(authItemCodeIntVal);
		AuthProccess authProccess = authProccessService.findByProcessId(proccessId);// 用户完成项
		if (null == authProccess) {
			authProccess = new AuthProccess();
			authProccess.setSuccessCode(0);
		}
		reportStatus.setItemDesc(authItem.getItemDesc());
		reportStatus.setItemName(authItem.getItemName());
		reportStatus.setItemIcon(authItem.getItemIcon());
		reportStatus.setItemCode(authItem.getAuthCode());
		reportStatus.setItemId(authItem.getItemId());

		if (null == proccessId) { // 未登录情况，返回未完成状态
			reportStatus.setStatus("0");
			return reportStatus;
		}

		switch (param) {
		case ALIPAY: // 支付宝
			AuthAlipay authAlipay = authAlipayService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authAlipay && null != flag && flag == 1) {
				authAlipay.setAuthStatus(EMStatusEnum.INIT.getCode());
				authAlipayService.resetStatus(authAlipay);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authAlipay);
			break;
		case FUND_CREDIT: // 公积金
			AuthAccumulation authAccumulation = authAccumulationService.findByProccessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authAccumulation && null != flag && flag == 1) {
				authAccumulation.setAuthStatus(AuthAccumulationStatusEnum.INIT.getCode());
				authAccumulationService.update(authAccumulation);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authAccumulation);
			break;
		case JINGDONG: // 京东
			AuthJd authJd = authJdService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authJd && null != flag && flag == 1) {
				authJd.setAuthStatus(EMStatusEnum.INIT.getCode());
				authJdService.resetStatus(authJd);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authJd);
			break;
		case MOBILE: // 手机
			AuthMobile authMobile = authMobileService.findByProcessIdAndType(proccessId, 0);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authMobile && null != flag && flag == 1) {
				authMobile.setResultStatus(MobileStatusEnum.UN_AUTHENTICATE.getCode());
				authMobileService.resetStatus(authMobile);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authMobile);
			break;
		case SESAME_CREDIT: // 芝麻信用
			AuthSecredit authSecredit = authSecreditService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authSecredit && null != flag && flag == 1) {
				authSecredit.setAuthStatus(EMStatusEnum.INIT.getCode());
				authSecreditService.resetStatus(authSecredit);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authSecredit);
			break;
		case SOCIAL_CREDIT: // 社保
			AuthSocial authSocial = authSocialService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authSocial && null != flag && flag == 1) {
				authSocial.setAuthStatus(AuthAccumulationStatusEnum.INIT.getCode());
				authSocialService.resetStatus(authSocial);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authSocial);
			break;
		case TAOBAO: // 淘宝
			AuthTaobao authTaobao = authTaobaoService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != authTaobao && null != flag && flag == 1) {
				authTaobao.setAuthStatus(EMStatusEnum.INIT.getCode());
				authTaobaoService.resetStatus(authTaobao);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, authTaobao);
			break;
		case BANK_CREDIT: // 央行征信
			AuthNetcredit netcredit = authNetcreditService.findByProcessId(proccessId);
			if (null != netcredit && null != flag && flag == 1) {
				netcredit.setCreditStatus(AuthCreditStatusEnum.INIT.getCode());
				authNetcreditService.update(netcredit);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
				reportStatus.setStatus("0");
				break;
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, netcredit);
			break;
		case CREDIT_CARD: // 信用卡
			AuthCreditcard creditcard = authCreditcardService.findByProcessId(proccessId);
			if (null != creditcard && null != flag && flag == 1) {
				creditcard.setAuthStatus(CreditStatusEnum.INIT.getCode());
				authCreditcardService.update(creditcard);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
				reportStatus.setStatus("0");
				break;
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, creditcard);
			break;
		case FOREIGN_CREDIT: // 机构版征信
			CreditAssure creditAssure = creditAssureService.findByProcessId(proccessId);
			// 重置认证信息认证状态和扣除用户对应该认证项的完成分
			if (null != creditAssure && null != flag && flag == 1) {
				creditAssure.setAssureStatus(AssureStatusEnum.Invalid.getCode());
				creditAssureService.resetStatus(creditAssure);
				this.deductSucCodeByAuthItemId(authProccess, authItemCodeIntVal);
			}
			reportStatus = checkStatus(param.getCode(), reportStatus, creditAssure);
			break;
		case IDENTITY_REAL: // 身份证认证（高级实名）
			AuthIdentity authIdentity = authIdentityService.findByProcessId(proccessId);
			if (null != authIdentity
					// 身份证正反面
					&& StringUtils.isNotBlank(authIdentity.getIdFront()) && StringUtils.isNotBlank(authIdentity.getIdBack())
					// 手持照
					&& StringUtils.isNotBlank(authIdentity.getIdHandheld())
					// 签名
					&& StringUtils.isNotBlank(cust.getSignatureImage())) {
				reportStatus.setStatus("1");
			} else {
				reportStatus.setStatus("0");
			}
			break;
		case VERIFY_FACE_PAIR: // 身份证认证（高级实名）
			AuthIdentity identity = authIdentityService.findByProcessId(proccessId);
			if (null != identity
					// 身份证正反面
					&& StringUtils.isNotBlank(identity.getIdFront()) && StringUtils.isNotBlank(identity.getIdBack())
					// 人脸照
					&& StringUtils.isNotBlank(identity.getIdFace())
					// 签名
					&& StringUtils.isNotBlank(cust.getSignatureImage())) {
				reportStatus.setStatus("1");
			} else {
				reportStatus.setStatus("0");
			}
			break;
		default: // 其他无过期时间
			reportStatus = checkReportStatus(param.getCode(), reportStatus, authProccess.getSuccessCode());
			break;
		}
		return reportStatus;
	}
}
